/*
 * This file is part of the Marmalade SDK Code Samples.
 *
 * (C) 2001-2012 Marmalade. All Rights Reserved.
 *
 * This source code is intended only as a supplement to the Marmalade SDK.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 */

#ifndef DATABASE_HANDLER_H
#define DATABASE_HANDLER_H

// Library includes
#include "IwUIElementPropertyBinding.h"

//-----------------------------------------------------------------------------

class IDatabaseObserver
{
public:
    virtual void NotifyDatabaseUpdate(int actionCode, char const* pDB,
        char const * pTbl, int64 rowId) = 0;
};

//-----------------------------------------------------------------------------
class CDatabaseHandler
{
public:
    CDatabaseHandler();
    virtual ~CDatabaseHandler();

    // Public interface
    bool OpenDatabase(const char* pFilename);
    bool OpenDatabaseInMemory();
    bool CloseDatabase();

    int Exec(const char* pSQL);
    bool ExecScalar(const char* pSQL, int& outResult);
    bool TableExists(const char* pTable);

    void AddObserver(IDatabaseObserver* pObserver);
    void RemoveObserver(IDatabaseObserver* pObserver);

    static CDatabaseHandler* Get();

private:
    // Private enums
    enum eStepResult
    {
        eRow,
        eDone,
        eError
    };

    // Private utils
    struct sqlite3_stmt* PrepareStatement(const char* pSQL);
    eStepResult StepStatement(sqlite3_stmt* pStatement);
    bool FinalizeStatement(sqlite3_stmt* pStatement);

    void NotifyUpdate(int actionCode, char const* pDB,
        char const* pTbl, int64 rowId);
    static void _NotifyUpdate(void * pData, int actionCode, char const* pDB,
        char const* pTbl, int64 rowId);

    // Member data
    struct sqlite3* m_DB;
    CIwArray<IDatabaseObserver*> m_Observers;
    static CDatabaseHandler* s_Singleton;
};

//-----------------------------------------------------------------------------
class CDataBinding : public CIwUIElementPropertyBinding, private IDatabaseObserver
{
public:
    IW_MANAGED_DECLARE(CDataBinding)
    CDataBinding();
    virtual ~CDataBinding();

    // IwPropertySetBinding virtuals
    virtual bool ParseAttribute(CIwTextParserITX* pParser, const char* pAttrName);
    virtual void DecomposeAttributes(CIwTextDecomposer* pDecomposer) const;
    virtual void Serialise();

    virtual bool GetProperty(CIwPropertyBase* pProperty);
    virtual bool SetProperty(CIwPropertyBase* pProperty);
    virtual void Clone(CIwPropertyBinding* pTarget) const;

private:
    // IDatabaseObserver virtuals
    virtual void NotifyDatabaseUpdate(int actionCode, char const* pDB,
        char const * pTbl, int64 rowId);

private:
    // Private utils
    int GetValue();
    void SetValue(int val);

    // Member data
    uint32  m_Property;
    int32   m_RowId;
};

#endif
